package com.relytosoft.mizar.media.analyze.services.service.structure.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.relytosoft.dubhe.common.core.base.page.PageQuery;
import com.relytosoft.dubhe.common.core.constant.CommonConstants;
import com.relytosoft.dubhe.common.core.exception.ServiceException;
import com.relytosoft.dubhe.common.core.object.ResponseResult;
import com.relytosoft.dubhe.common.core.utils.BeanCopyUtils;
import com.relytosoft.dubhe.common.redis.utils.RedisUtil;
import com.relytosoft.mizar.media.analyze.api.pojo.dto.AyStructurePicByPicDto;
import com.relytosoft.mizar.media.analyze.api.pojo.vo.AyStructurePicByPicVo;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructurePicByPicService;
import com.relytosoft.mizar.media.common.config.properties.MizarAnalyzeProperties;
import com.relytosoft.mizar.media.common.constant.AyCacheConstants;
import com.relytosoft.mizar.media.common.entity.pojo.dto.ComparisonTaskReqDto;
import com.relytosoft.mizar.media.external.api.analyze.request.StruDataReqDetailDto;
import com.relytosoft.mizar.media.external.api.analyze.response.DataConditionRespVo;
import com.relytosoft.mizar.media.external.api.analyze.response.DataResqVo;
import com.relytosoft.mizar.media.external.api.analyze.response.DataVo;
import com.relytosoft.mizar.media.external.api.analyze.response.PicComparisonResultResDto;
import com.relytosoft.mizar.media.external.api.analyze.service.StructureService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author lj
 * @date 2022/6/9 17:38
 */
@Service
public class AyStructurePicByPicServiceImpl implements AyStructurePicByPicService {

    @Resource
    private StructureService structureService;

    @Resource
    private MizarAnalyzeProperties mizarAnalyzeProperties;


    @Override
    public boolean create(AyStructurePicByPicDto ayStructurePicByPicDto) {
        //创建ComparisonTaskReqDto
        ComparisonTaskReqDto comparisonTaskReqDto = BeanUtil.copyProperties(ayStructurePicByPicDto, ComparisonTaskReqDto.class);
        comparisonTaskReqDto.setComparisonTaskId(UUID.fastUUID().toString());
        comparisonTaskReqDto.setBeginTime(ayStructurePicByPicDto.getBeginTime().getTime());
        comparisonTaskReqDto.setEndTime(ayStructurePicByPicDto.getEndTime().getTime());
        //创建任务
        ResponseResult taskResult = structureService.createPickTask(comparisonTaskReqDto);
        boolean isSuccess = taskResult.getCode() == CommonConstants.SUCCESS;
        if (isSuccess) {
            //存入redis并设置过期时间
            RedisUtil.sSetAndTime(
                    AyCacheConstants.AY_STRUCTURE_PIC_BY_PIC
                    , mizarAnalyzeProperties.getPicBypicExpirationTime(),
                    JSON.toJSONString(comparisonTaskReqDto));
        }
        return isSuccess;
    }

    @Override
    public boolean delete(String comparisonTaskId) {
        ResponseResult taskResult = structureService.deletePickTask(comparisonTaskId);
        boolean isSuccess = taskResult.getCode() == CommonConstants.SUCCESS;
        //获取redis中的数据
        if (isSuccess) {
            Set<Object> objects = RedisUtil.sGet(AyCacheConstants.AY_STRUCTURE_PIC_BY_PIC);
            for (Object object : objects) {
                ComparisonTaskReqDto comparisonTaskReqDto = JSON.parseObject(object.toString(), ComparisonTaskReqDto.class);
                if (comparisonTaskReqDto.getComparisonTaskId().equals(comparisonTaskId)) {
                    RedisUtil.setRemove(AyCacheConstants.AY_STRUCTURE_PIC_BY_PIC, JSON.toJSONString(comparisonTaskReqDto));
                    break;
                }
            }
        }
        return isSuccess;
    }

    @Override
    public List<AyStructurePicByPicVo> select() {
        List<AyStructurePicByPicVo> ayStructurePicByPicVos = new ArrayList<>();
        Set<Object> objects = RedisUtil.sGet(AyCacheConstants.AY_STRUCTURE_PIC_BY_PIC);
        for (Object object : objects) {
            ComparisonTaskReqDto comparisonTaskReqDto = JSON.parseObject(object.toString(), ComparisonTaskReqDto.class);
            AyStructurePicByPicVo structurePicByPicVo = BeanCopyUtils.copy(comparisonTaskReqDto, AyStructurePicByPicVo.class);
            structurePicByPicVo.setBeginTime(new Date(comparisonTaskReqDto.getBeginTime()));
            structurePicByPicVo.setEndTime(new Date(comparisonTaskReqDto.getEndTime()));
            //赋值
            ayStructurePicByPicVos.add(structurePicByPicVo);
        }
        return ayStructurePicByPicVos;
    }


    @Override
    public JSONObject selectResult(PageQuery pageQuery, String comparisonTaskId) {
        parameterProcessing(pageQuery);
        //封装查询条件
        StruDataReqDetailDto struDataReqDetailDto = new StruDataReqDetailDto();
        //获取redis中的数据
        Object object = RedisUtil.get(AyCacheConstants.AY_STRUCTURE_PIC_BY_PIC_RECEIVE + comparisonTaskId);
        //如果objects为空，则说明没有数据
        if (object == null) {
            throw new ServiceException("无效的ComparisonTaskID");
        }
        //object转为PicComparisonResultResDto
        PicComparisonResultResDto picComparisonResultResDto = JSON.parseObject(object.toString(), PicComparisonResultResDto.class);
        //获取结果
        List<DataVo> dataVoList = picComparisonResultResDto.getComparisonResultData();
        //收集dataVoList中的id
        List<String> idList = new ArrayList<>();
        dataVoList.forEach(dataVo -> {
            idList.add(dataVo.getId());
        });
        struDataReqDetailDto.setIds(idList);
        //默认按照时间排序
        if ("markTime".equals(pageQuery.getOrderByColumn()) || pageQuery.getOrderByColumn() == null) {
            struDataReqDetailDto.setSortBy("markTime");
            struDataReqDetailDto.setSort("DESC");
            struDataReqDetailDto.setPageNo(pageQuery.getPageNum());
            struDataReqDetailDto.setPageSize(pageQuery.getPageSize());
        } else if ("score".equals(pageQuery.getOrderByColumn())) {
            //对需要查询的id数据按照score排序
            dataVoList.sort(new Comparator<DataVo>() {
                @Override
                public int compare(final DataVo o1, final DataVo o2) {
                    return o2.getScore().compareTo(o1.getScore());
                }
            });
            List<String> newIds = new ArrayList<>();
            //dataVoList是数据总量。根据分页数据筛选出dataVoList中需要查询的数量即可
            int i;
            for (int index = i = pageQuery.getPageNum() * pageQuery.getPageSize() - pageQuery.getPageSize(); i < pageQuery.getPageSize() + index && i <= dataVoList.size() - 1; ++i) {
                newIds.add(dataVoList.get(i).getId());
            }
            struDataReqDetailDto.setIds(newIds);
            struDataReqDetailDto.setPageNo(1);
            struDataReqDetailDto.setPageSize(pageQuery.getPageSize());
        }
        //查询
        ResponseResult responseResult = structureService.searchStructureDetail(struDataReqDetailDto);
        DataConditionRespVo resultStructure = JSONObject.parseObject(JSON.toJSONString(responseResult.getData()), new TypeReference<DataConditionRespVo>() {
        });

        if (resultStructure != null && CollectionUtils.isNotEmpty(resultStructure.getItems())) {
            for (DataVo dataVo : dataVoList) {
                for (DataResqVo respVo : resultStructure.getItems()) {
                    if (1 == respVo.getDataType()) {
                        if (!dataVo.getId().equals(respVo.getPerson().getString("_id"))) {
                            continue;
                        }
                        respVo.setScore(dataVo.getScore());
                    } else if (2 == respVo.getDataType()) {
                        if (!dataVo.getId().equals(respVo.getMotorVehicle().getString("_id"))) {
                            continue;
                        }
                        respVo.setScore(dataVo.getScore());
                    } else if (3 == respVo.getDataType()) {
                        if (!dataVo.getId().equals(respVo.getNonMotorVehicle().getString("_id"))) {
                            continue;
                        }
                        respVo.setScore(dataVo.getScore());
                    } else {
                        if (respVo.getDataType() != null || !dataVo.getId().equals(respVo.getFace().getString("recordId"))) {
                            continue;
                        }
                        respVo.setScore(dataVo.getScore());
                    }
                }
            }
            if (pageQuery.getOrderByColumn() != null && "score".equals(pageQuery.getOrderByColumn())) {
                resultStructure.getItems().sort(new Comparator<DataResqVo>() {
                    @Override
                    public int compare(final DataResqVo o1, final DataResqVo o2) {
                        return o2.getScore().compareTo(o1.getScore());
                    }
                });
                int pageCount = dataVoList.size() % pageQuery.getPageSize() == 0 ?
                        dataVoList.size() / pageQuery.getPageSize() : dataVoList.size() / pageQuery.getPageSize() + 1;
                //计算页数
                resultStructure.setPageCount(pageCount);
                //计算总数
                resultStructure.setTotal(dataVoList.size());
            }
        }
        return JSONObject.parseObject(JSON.toJSONString(resultStructure));
    }


    private void parameterProcessing(PageQuery pageQuery) {
        Integer pageNum = pageQuery.getPageNum();
        Integer pageSize = pageQuery.getPageSize();
        if (pageNum == null) {
            pageQuery.setPageNum(1);
        }
        if (pageSize == null) {
            pageQuery.setPageSize(10);
        }
    }
}
